package com.zhou.message.controller;

import com.github.pagehelper.PageInfo;
import com.zhou.framework.util.PageUtil;
import com.zhou.framework.util.SessionUtil;
import com.zhou.framework.util.SettingUtil;
import com.zhou.util.NumberUtil;
import com.zhou.util.ObjectUtil;
import com.zhou.framework.aop.anotation.LogOption;
import com.zhou.framework.aop.enums.LogLevel;
import com.zhou.framework.dto.IntegersDto;
import com.zhou.framework.dto.LongDto;
import com.zhou.framework.dto.LongsDto;
import com.zhou.framework.dto.TwoLongDto;
import com.zhou.framework.model.RS;
import com.zhou.framework.util.FileUploaderUtil;
import com.zhou.message.dao.Attachment;
import com.zhou.message.dao.MessageTemplate;
import com.zhou.message.dao.MessageTemplateReceiver;
import com.zhou.message.dao.SendMessage;
import com.zhou.message.dto.*;
import com.zhou.message.model.MessageReceiver;
import com.zhou.message.model.MessageSendModel;
import com.zhou.message.service.*;
import com.zhou.org.common.EnumConstant;
import com.zhou.org.dao.Org;
import com.zhou.org.model.SendResult;
import com.zhou.org.service.OrgService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@Slf4j
@RestController
@RequestMapping("/message")
public class MessageController {
    @Autowired
    private SendMessageService sendMessageService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private OrgService orgService;
    @Autowired
    private ReceiveMessageService receiveMessageService;
    @Autowired
    private MessageTemplateService messageTemplateService;
    @Autowired
    private MessageTemplateReceiverService messageTemplateReceiverService;


    @PostMapping("/userReceiveCount")
    @ApiOperation("查询收信箱统计")
    @LogOption(LogLevel.QUERY)
    public Object getReceiveCount(){
        Integer userId = SessionUtil.getCurrentUserId();
        Map<String,Integer> l = messageService.getUserReceiveCount(userId);
        RS r = RS.success();
        int total = 0;
        for (String s : l.keySet()) {
            total += NumberUtil.safeToInteger(l.get(s),0);
            r.set(s, NumberUtil.safeToInteger(l.get(s),0));
        }
        r.set("total",total);
        return r;
    }

    @PostMapping("/receiveList")
    @ApiOperation("查询收信箱")
    @LogOption(LogLevel.QUERY)
    public Object getReceivePageList(@RequestBody SystemMessageQueryDto dto){
        dto.setToUserId(SessionUtil.getCurrentUserId());
        PageUtil.offsetPage(dto);
        List<SystemMessagePageDto> l= messageService.getReceivePageList(dto);
        return PageUtil.result(dto,l);
    }

    @PostMapping("/homeList")
    @ApiOperation("查询首页未读消息")
    @LogOption(LogLevel.QUERY)
    public Object getHomeMessageList(@RequestBody SystemMessageQueryDto dto){
        dto.setToUserId(SessionUtil.getCurrentUserId());
        dto.setReadStatus(0);
        dto.setPageNum(1);
        dto.setPageSize(SettingUtil.getInteger("home","messageShowNum",5));
        PageUtil.offsetPage(dto);
        List<SystemMessagePageDto> l = messageService.getReceivePageList(dto);
        PageInfo<SystemMessagePageDto> pageInfo = new PageInfo<>(l);
        return RS.success().set("messageList",l).set("total",pageInfo.getTotal());
    }

    @PostMapping("/sendList")
    @ApiOperation("查询发信箱")
    @LogOption(LogLevel.QUERY)
    public Object getSendPageList(@RequestBody SystemMessageQueryDto dto){
        dto.setFromUserId(SessionUtil.getCurrentUserId());
        dto.setDeleteFlag(0);
        PageUtil.offsetPage(dto);
        List<SendMessagePageDto> l= messageService.getSendPageList(dto);
        return PageUtil.result(dto,l);
    }

    @PostMapping("/systemList")
    @ApiOperation("系统消息列表")
    @LogOption(LogLevel.QUERY)
    public Object getSystemMessageList(@RequestBody SystemMessageQueryDto dto){
        PageUtil.offsetPage(dto);
        List<SystemMessagePageDto> list= messageService.getSendMessageList(dto);
        return PageUtil.result(dto,list);
    }

    @PostMapping("/send")
    @ApiOperation("发送消息")
    @LogOption(LogLevel.MESSAGE)
    public Object sendMessage(@RequestBody @Validated MessageSendDto dto){
        SendMessage message = new SendMessage();
        message.setContent(dto.getContent());
        message.setType(dto.getType());
        message.setLevel(dto.getLevel());
        message.setTitle(dto.getTitle());
        message.setFromUserId(SessionUtil.getCurrentUserId());
        message.setTimer(dto.getTimer());
        if(ObjectUtil.isNotEmpty(dto.getReceivers())){
            List<Org> orgObjects = orgService.getOrgObjects(dto.getReceivers());
            for (Org org : orgObjects) {
                MessageReceiver receiver = new MessageReceiver();
                receiver.setOrgId(org.getOrgId());
                receiver.setOrgType(org.getOrgType());
                receiver.setUserId(org.getUserId());
                receiver.setRecieveType(EnumConstant.MSG_RECEIVE_TYPE_NORMAL);
                message.addReceiver(receiver);
            }
        }
        if(ObjectUtil.isNotEmpty(dto.getDuplicates())){
            List<Org> orgObjects = orgService.getOrgObjects(dto.getDuplicates());
            for (Org org : orgObjects) {
                MessageReceiver receiver = new MessageReceiver();
                receiver.setOrgId(org.getOrgId());
                receiver.setOrgType(org.getOrgType());
                receiver.setUserId(org.getUserId());
                receiver.setRecieveType(EnumConstant.MSG_RECEIVE_TYPE_CC);
                message.addReceiver(receiver);
            }
        }
        if(ObjectUtil.isNotEmpty(dto.getFiles())){
            List<Attachment> attachments = FileUploaderUtil.decodeAttachments(dto.getFiles());
            for (Attachment attach : attachments) {
                attach.setIsPub(0);
                message.addAttachment(attach);
            }
        }
        try{
            messageService.addMessage(message);
            if(Objects.equals(dto.getLevel(),1)){
                MessageSendModel qd = new MessageSendModel();
                qd.setSendId(message.getId());
                messageService.sendSynMessage(qd);
            }
            return RS.success();
        }catch (Exception e){
            log.error("发送消息失败！",e);
            return RS.failed("发送消息失败！");
        }
    }

    @PostMapping("/read")
    @ApiOperation("读取消息")
    @LogOption(LogLevel.EDIT)
    public Object readMessage(@RequestBody MessageStatusDto dto){
        receiveMessageService.updateReceiveMessageStatus(dto.getStatus(),dto.getIds());
        return RS.success();
    }

    @PostMapping("/reSendFail")
    @ApiOperation("失败消息重发")
    @LogOption(LogLevel.EDIT)
    public Object reSendFailMessage(@RequestBody LongDto dto){
        if(dto.getId() > 0){
            MessageSendModel d = new MessageSendModel();
            d.setSendId(dto.getId());
            d.setTimer(0);
            d.setStatus(EnumConstant.MSG_SEND_STATUS_FAIL);
            try{
                SendResult result = messageService.sendSynMessage(d);
                if(ObjectUtil.isNotEmpty(result.failedSendDetail)&& ObjectUtil.isEmpty(result.successSendDetail)){
                    return RS.failed("发送失败");
                }else if(ObjectUtil.noEmpty(result.failedSendDetail,result.successSendDetail)){
                    return RS.failed("部分接收人发送失败");
                }
            }catch (Exception e){
                log.error("发送消息失败！",e);
                return RS.failed("发送消息失败");
            }

        }
        return RS.success();
    }

    @PostMapping("/reSend")
    @ApiOperation("重发消息")
    @LogOption(LogLevel.EDIT)
    public Object reSend(@RequestBody TwoLongDto d){
        if(d.getId1() > 0 && d.getId2() > 0){
            MessageSendModel dto = new MessageSendModel();
            dto.setTimer(0);
            dto.setSendId(d.getId1());
            dto.setDetailId(d.getId2());
            try{
                SendResult result = messageService.sendSynMessage(dto);
                if(ObjectUtil.isNotEmpty(result.failedSendDetail)){
                    return RS.failed("发送失败！");
                }
            }catch (Exception e){
                log.error("发送消息失败！",e);
                return RS.failed("发送消息失败！");
            }
        }
        return RS.success();
    }

    @PostMapping("/updateStatus")
    @ApiOperation("标记消息状态")
    @LogOption(LogLevel.EDIT)
    public Object updateStatus(@RequestBody MessageStatusDto dto){
        receiveMessageService.updateReceiveMessageStatus(dto.getStatus(),dto.getIds());
        return RS.success();
    }

    @DeleteMapping("/deleteReceiveMessage")
    @ApiOperation("删除已接收的消息")
    @LogOption(LogLevel.DELETE)
    public Object deleteReceiveMessage(@RequestBody LongsDto dto){
        receiveMessageService.deleteReceiveMessage(dto.getIds());
        return "ok";
    }
    @DeleteMapping("/deleteSendMessage")
    @ApiOperation("删除发送的消息")
    @LogOption(LogLevel.DELETE)
    public Object deleteSendMessage(@RequestBody LongsDto dto){
        sendMessageService.deleteSendMessageFalse(dto.getIds());
        return RS.success();
    }

    @GetMapping("/getToReadCount")
    @ApiOperation("查询未读消息")
    @LogOption(LogLevel.QUERY)
    public Object getToReadCount(){
        Map<String,Object> par = new HashMap<>(1);
        if(SessionUtil.isLogin()){
            par.put("userId",SessionUtil.getCurrentUserId());
            par.put("status",0);
            return messageService.getReceiveCount(par);
        }
        return 0;

    }

    @GetMapping("/template/allCatalog")
    @ApiOperation("查询消息模板分类")
    public Object getAllCatalog(){
        List<String> list = messageTemplateService.getAllMessageTemplateCatalog();
        return RS.data(list);
    }

    @PostMapping("/template/list")
    @ApiOperation("消息模板列表")
    public Object getTemplateList(@RequestBody MessageTemplateQueryDto dto){
        PageUtil.offsetPage(dto);
        List<MessageTemplate> list = messageTemplateService.getMessageTemplateList(dto);
        return PageUtil.result(dto,list);
    }

    @GetMapping("/template/get")
    @ApiOperation("id获得消息模板")
    public Object get(@RequestParam Integer id){
        List<MessageTemplateReceiver> receivers = null;
        MessageTemplate template = messageTemplateService.getById(id);
        if(template != null){
            receivers = messageTemplateReceiverService.getTemplateReceivers(id);
        }
        return RS.success().set("template",template).set("receivers",receivers);
    }

    @DeleteMapping("/template/delete")
    @LogOption(LogLevel.DELETE)
    @ApiOperation("删除消息模板")
    public Object deleteTemplate(@RequestBody IntegersDto dto){
        messageTemplateService.deleteMessageTemplate(dto.getIds());
        return RS.success();
    }

    @PostMapping("/template/save")
    @LogOption(LogLevel.EDIT)
    @ApiOperation("保存消息模板")
    public Object saveTemplate(@RequestBody @Validated MessageTemplateSaveDto dto){

        MessageTemplate template = messageTemplateService.getTemplateByCode(dto.getCode());
        if(template != null && !Objects.equals(template.getId(),dto.getId())){
            return RS.failed("模板代码已存在");
        }
        if(template == null){
            template = new MessageTemplate();
        }
        BeanUtils.copyProperties(dto,template);
        List<MessageTemplateReceiver> receiverList = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(dto.getOrgIds())){
            List<Org> orgList = orgService.getOrgObjects(dto.getOrgIds());
            for (Org org : orgList) {
                MessageTemplateReceiver r = new MessageTemplateReceiver();
                r.setOrgId(org.getOrgId());
                r.setOrgType(org.getOrgType());
                r.setUserId(org.getUserId());
                receiverList.add(r);
            }
        }
        messageTemplateService.saveMessageTemplate(template,receiverList);
        return RS.success();
    }

    @PostMapping("/template/send")
    @LogOption(LogLevel.MESSAGE)
    @ApiOperation("通过消息模板发送消息")
    public Object sendByTemplate(@RequestBody @Validated MessageTemplateSendDto dto){
        List<MessageReceiver> receiverList = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(dto.getOrgIds())){
            List<Org> orgList = orgService.getOrgObjects(dto.getOrgIds());
            for (Org org : orgList) {
                MessageReceiver r = new MessageReceiver();
                r.setOrgId(org.getOrgId());
                r.setOrgType(org.getOrgType());
                r.setUserId(org.getUserId());
                r.setRecieveType(EnumConstant.MSG_RECEIVE_TYPE_NORMAL);
                receiverList.add(r);
            }
        }

        Map<String,Object> par = dto.getParam();
        messageService.sendMessageByTemplate(dto.getId(),par,receiverList);
        return RS.success();
    }
}
